package zy.blue7.rest.ws;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/ws/{userId}")
@Component
public class WebSocket {
    private ObjectMapper objectMapper=new ObjectMapper();


    private static ConcurrentHashMap<Long, WebSocket> webSocketMap = new ConcurrentHashMap<>();
    //实例一个session，这个session是websocket的session
    private Session session;

    //新增一个方法用于主动向客户端发送消息
    public static void sendMessage(Object message, Long userId) {
        WebSocket webSocket = webSocketMap.get(userId);
        if (webSocket != null) {
            try {
                webSocket.session.getBasicRemote().sendText(JSON.toJSONString(message));
                System.out.println("【websocket消息】发送消息成功,用户=" + userId + ",消息内容" + message.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static ConcurrentHashMap<Long, WebSocket> getWebSocketMap() {
        return webSocketMap;
    }

    public static void setWebSocketMap(ConcurrentHashMap<Long, WebSocket> webSocketMap) {
        WebSocket.webSocketMap = webSocketMap;
    }


    /**
     * org.apache.tomcat.websocket.pojo.PojoMethodMapping.getOnOpenArgs
     * todo 看这里可以表明，这几个指定注解的方法，只能有这几种入参，其中自定义入参类型只能是 string类型，并且只有  /ws/{userId} 中的 userId 才会有值
     * org.apache.tomcat.websocket.pojo.PojoMethodMapping#buildArgs(org.apache.tomcat.websocket.pojo.PojoPathParam[], java.util.Map, javax.websocket.Session, javax.websocket.EndpointConfig, java.lang.Throwable, javax.websocket.CloseReason)
     *
     * @param session
     * @param userId
     */
    //前端请求时一个websocket时
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Long userId, @PathParam("message") String message) {
        this.session = session;
        webSocketMap.put(userId, this);
        sendMessage("CONNECT_SUCCESS", userId);
        System.out.println("【websocket消息】有新的连接,连接id：" + userId);
    }

    //前端关闭时一个websocket时
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        webSocketMap.remove(userId);
        System.out.println("【websocket消息】连接断开,总数:" + webSocketMap.size());
    }


    //前端向后端发送消息
    @SneakyThrows
    @OnMessage
    public void onMessage(String message, @PathParam("userId") Long userId) {
        if (!message.equals("ping")) {
            System.out.println("【websocket消息】收到客户端发来的消息:" + message);
        }


       if (message.equalsIgnoreCase("1")||message.equalsIgnoreCase("2")){

       }else {
           Message readValue = objectMapper.readValue(message, Message.class);
           System.out.println(readValue);
           Long userId1 = readValue.getSessionId();

           sendMessage(readValue,userId1);
       }

    }

}
